using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace S
{
    /// <summary>
    /// the screen thumbnail entity
    /// </summary>
    public class ScreenThumbnail : S.Entity
    {
        /// <summary>
        /// default constructor
        /// </summary>
        /// <param name="pScreen">the screen whose thumbnail we need</param>
        public ScreenThumbnail(S.Screen pScreen)
            : base(new Point(), new Size())
        {
            // save the screen
            this.mScreen = pScreen;

            // initialize the usercontrol and picture box and label
            this.mControl = new UserControl();
            this.mPicture = new PictureBox();
            this.mLabel = new Label();

            // initialize the usercontrol and add the picturebox and label
            this.mControl.SuspendLayout();

            // initialize the picturebox
            this.mPicture.BackColor = Color.White;
            this.mPicture.BorderStyle = BorderStyle.FixedSingle;
            this.mPicture.Location = new Point(S.StaticVariables.Instance.ThumbnailMargin.Width, S.StaticVariables.Instance.ThumbnailMargin.Height);
            this.mPicture.Size = S.StaticVariables.Instance.ThumbnailSize;
            this.mPicture.MouseDown += new MouseEventHandler(this.OnMouseDown);
            this.mPicture.Click += new EventHandler(this.OnClick);
            this.mPicture.Image = pScreen.Thumbnail;

            // initialize the label
            this.mLabel.Name = "Label " + pScreen.Name;
            this.mLabel.Location = new Point(S.StaticVariables.Instance.ThumbnailMargin.Width, S.StaticVariables.Instance.ThumbnailSize.Height + S.StaticVariables.Instance.ThumbnailMargin.Height * 2);
            this.mLabel.Size = new Size(S.StaticVariables.Instance.ThumbnailSize.Width, 17);
            this.mLabel.Text = pScreen.Name;
            this.mLabel.TextAlign = ContentAlignment.MiddleCenter;
            this.mLabel.MouseDown += new MouseEventHandler(this.OnMouseDown);
            this.mLabel.Click += new EventHandler(this.OnClick);

            // initialize the usercontrol
            this.mControl.BackColor = Color.Coral;
            this.mControl.Size = new Size(S.StaticVariables.Instance.ThumbnailSize.Width + S.StaticVariables.Instance.ThumbnailMargin.Width * 2, S.StaticVariables.Instance.ThumbnailSize.Height + S.StaticVariables.Instance.ThumbnailMargin.Height * 3 + 17);
            this.mControl.MouseDown += new MouseEventHandler(this.OnMouseDown);
            this.mControl.Click += new EventHandler(this.OnClick);

            // add the picturebox and label
            //this.mControl.Controls.Add(this.mPicture);
            this.mControl.Controls.Add(this.mLabel);

            // we are done here
            this.mControl.ResumeLayout(false);
        }

        /// <summary>
        /// the control associated with this screen thumbnail
        /// </summary>
        public UserControl Control
        {
            get
            {
                return this.mControl;
            }
        }

        /// <summary>
        /// the screen associated with this screen thumbnail
        /// </summary>
        public S.Screen Screen
        {
            get
            {
                return this.mScreen;
            }
        }

        /// <summary>
        /// checks whether the x and y points hit this entity
        /// </summary>
        /// <param name="pX">the x position to check</param>
        /// <param name="pY">the y position to check</param>
        /// <returns>true if this entity hits false otherwise</returns>
        public override bool HitTest(int pX, int pY)
        {
            // return whether the point rectangle intersects with the bounding box
            return this.mBoundingBox.IntersectsWith(new Rectangle(pX, pY, 1, 1));
        }

        /// <summary>
        /// draw the entity on the given graphics
        /// </summary>
        /// <param name="pGraphics">the graphics to draw on</param>
        public override void Draw(Graphics pGraphics)
        {
            // draw the screen thumbnail
            using (Bitmap bitmap = Bitmap.FromHbitmap(this.mControl.Handle))
            {
                pGraphics.DrawImage(bitmap, this.mBoundingBox.Location);
            }
        }

        /// <summary>
        /// refresh the thumbnail image
        /// </summary>
        public void RefreshThumbnail()
        {
            this.mPicture.Invalidate();
        }

        /// <summary>
        /// handles the selection of this entity
        /// </summary>
        protected override void OnSelect()
        {
            // set the background color of the control to red
            this.mControl.BackColor = Color.Red;
        }

        /// <summary>
        /// handles the deselection of this entity
        /// </summary>
        protected override void OnDeselect()
        {
            // set the background color of the control to control back color
            this.mControl.BackColor = SystemColors.Control;
        }

        /// <summary>
        /// handles the movement of this entity
        /// </summary>
        /// <param name="pDeltaX">the relative x position to move</param>
        /// <param name="pDeltaY">the relative y position to move</param>
        protected override void OnMove(int pDeltaX, int pDeltaY)
        {
            this.mBoundingBox.X += pDeltaX;
            this.mBoundingBox.Y += pDeltaY;
        }

        /// <summary>
        /// handles the scale of this entity
        /// </summary>
        /// <param name="pScaleRectangle">the rectangle to scale to</param>
        protected override void OnScale(Rectangle pScaleRectangle)
        {
            this.mBoundingBox.Width = pScaleRectangle.Width;
            this.mBoundingBox.Height = pScaleRectangle.Height;
        }

        /// <summary>
        /// releases all resources associated with this entity
        /// </summary>
        public override void Dispose()
        {
            if (this.mControl != null)
            {
                // dispose the control and its elements
                this.mControl.Dispose();

                // and set it to null
                this.mControl = null;
            }

            // clear the screen
            this.mScreen = null;
        }

        /// <summary>
        /// clones this entity and returns an exact copy
        /// </summary>
        /// <returns>an exact copy of this screen thumbnail</returns>
        public override object Clone()
        {
            return new S.ScreenThumbnail(this.mScreen);
        }

        /// <summary>
        /// handles mouse down events
        /// </summary>
        /// <param name="pSender">the sender of the event</param>
        /// <param name="pData">the mouse event args associated</param>
        private void OnMouseDown(object pSender, MouseEventArgs pData)
        {
            if (this.MouseDown != null)
            {
                this.MouseDown.Invoke(this, new EventArgs());
            }
        }

        /// <summary>
        /// handles the click
        /// </summary>
        /// <param name="pSender">the sender of the event</param>
        /// <param name="pData">the event args associated</param>
        private void OnClick(object pSender, EventArgs pData)
        {
            if (this.Click != null)
            {
                this.Click.Invoke(this, new EventArgs());
            }
        }

        /// <summary>
        /// the mouse click event
        /// </summary>
        public event EventHandler Click;

        /// <summary>
        /// the mouse down event
        /// </summary>
        public event EventHandler MouseDown;

        /// <summary>
        /// the screen associated with this screen thumbnail
        /// </summary>
        private S.Screen mScreen;

        /// <summary>
        /// the internal user control associated with this screen thumbnail
        /// </summary>
        private UserControl mControl;

        /// <summary>
        /// the picture box associated with this screen thumbnail
        /// </summary>
        private PictureBox mPicture;

        /// <summary>
        /// the label of this screen thumbnail
        /// </summary>
        private Label mLabel;
    }
}
